#!/usr/bin/python
# Any live cell with fewer than two live neighbours dies, as if caused by underpopulation.
# Any live cell with more than three live neighbours dies, as if by overcrowding.
# Any live cell with two or three live neighbours lives on to the next generation.
# Any dead cell with exactly three live neighbours becomes a live cell.

 # lolz, global varibles. Bad, I know. Will be fixed later.

class GameOfLife:
    def __init__(self, start):
        self.cells = {}
        for cell in start: # populates the initial cell dict
            self.cells[cell] = 0
        self.dead_list = []
        
    def check_adjacent(self,cell, skip=False): # "skip" is used to skip the live cell only bits when checked dead cells
        number_adjcant = 0 # of adjaenct cells
        for x in range(-1,2):
            for y in range(-1,2):
                if (cell[0]+x, cell[1]+y) in self.cells:
                    number_adjcant += 1
                else:
                    if skip == False: self.dead_list.append((cell[0]+x, cell[1]+y)) # adds the dead ajacent cell to dead_list
        if skip == False: number_adjcant -= 1 # self != neighbor
        return (number_adjcant)

    def step(self): 
        self.dead_list = [] # resets the dead list
        cells_copy = dict(self.cells) # so it doesn't update the board while still iterating through it, which would screw things up
        for cell in self.cells:
            if   self.check_adjacent(cell) < 2:
                del cells_copy[cell]
            elif self.check_adjacent(cell) > 3:
                del cells_copy[cell]
            elif self.check_adjacent(cell) in [2,3]:
                cells_copy[cell] += 1
        for dead_cell in self.dead_list: # iterates over all dead cells that are adjacent to a live cell
            if self.check_adjacent(dead_cell, True) == 3:
                cells_copy[dead_cell] = 0
        self.cells = cells_copy

